<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>购物车</title>
  <style>
    .active {
      background-color: #ddd;
    }

    .message-box {
      padding: 10px 20px;
    }

    .success {
      background: #4fc08d;
      border: 1px solid #42b983;
    }

    .warning {
      background: #f66;
      border: 1px solid #d63200;
    }

    .message-box-close {
      float: right;
    }

    /* 动画相关样式 */
    /* 入场之前状态 */
    /* .fade-enter,
    .fade-leave-to {
      opacity: 0
    } */

    /* 过度定义 */
    /* .fade-enter-active,
    .fade-leave-active {
      transition: opacity 1.5s
    } */
  </style>
</head>

<body>
  <!-- 宿主文件 -->
  <div id="app">
    <!-- 弹窗组件 -->
    <!-- <message :show.sync="show" class="success"> -->
    <message ref="msgSuccess" class="success">
      <!-- 命名为title插槽内容 -->
      <template v-slot:title="slotProps">
        <strong>{{slotProps.title}}</strong>
      </template>
      <!-- 默认插槽内容 -->
      <template v-slot:default>
        新增课程成功!
      </template>
    </message>

    <!-- <message :show.sync="showWarn" class="warning"> -->
    <message ref="msgWarning" class="warning">
      <!-- 命名为title插槽内容 -->
      <template v-slot:title>
        <strong>警告</strong>
      </template>
      <!-- 默认插槽内容 -->
      <template v-slot:default>
        请输入课程名称!
      </template>
    </message>

    <h2 :title="title">
      <!-- 插值文本 -->
      {{title}}
    </h2>

    <!-- toolbar -->
    <div class="toolbar">
      <button @click="$bus.$emit('message-close')">清空提示框</button>
    </div>

    <!-- 新增课程 -->
    <course-add v-model="course" @add-course="addCourse"></course-add>
    <!-- <course-add :value="course" @input="course=$event" @add-course="addCourse"></course-add> -->

    <!-- 批量更新价格 -->
    <p>
      <input type="text" v-model.number="price">
      <button @click="batchUpdate">批量更新价格</button>
    </p>

    <!-- 列表组件 -->
    <course-list :courses="courses"></course-list>

    <!-- 商品总数 -->
    <p>
      <!-- 表达式 -->
      <!-- 课程总数：{{courses.length + '门'}} -->
      <!-- 计算属性 -->
      <!-- 课程总数：{{total}} -->
      <!-- 监听器 -->
      课程总数：{{totalCount}}
    </p>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
  <script src="vue.js"></script>
  <script>
    // 总线
    Vue.prototype.$bus = new Vue();

    // 弹窗组件
    Vue.component('message', {
      // props: ['show'],
      data() {
        return {
          show: false
        }
      },
      template: `
        <transition name="fade" 
          @before-enter="beforeEnter"
          @enter="enter"
          @before-leave="beforeLeave"
          @leave="leave">
          <div class="message-box" v-if="show">
            <!--具名插槽-->
            <slot name="title" title="来自message的标题">默认标题</slot>
            <!--通过slot获取传入内容-->
            <slot></slot>
            <span class="message-box-close" 
              @click="toggle">X</span>
          </div>
        </transition>
      `,
      mounted() {
        this.$bus.$on('message-close', () => {
          this.toggle()
        })
      },
      methods: {
        toggle() {
          this.show = !this.show;
        },
        beforeEnter(el){
          // 动画初始状态
          el.style.opacity = 0;
        },
        enter(el, done){
          Velocity(el, { opacity: 1 }, { duration: 1500, complete: done })
        },
        beforeLeave(el){
          // 动画初始状态
          el.style.opacity = 1;
        },
        leave(el, done){
          Velocity(el, { opacity: 0 }, { duration: 1500, complete: done })
        },
      },
    })

    // 课程新增组件
    Vue.component('course-add', {
      props: ['val'],
      model: {
        value: 'val',
        event: 'change'
      },
      template: `
        <div>
          <!-- 用户输入 -->
          <p>
            <input type="text" :value="val" 
              @change="onChange"
              v-on:keydown.enter="addCourse"
              ref="inp">
            <button @click="addCourse">新增</button>
          </p>
        </div>
      `,
      methods: {
        addCourse() {
          // 派发事件通知父组件新增课程
          this.$emit('add-course')

        },
        onChange(e) {
          this.$emit('change', e.target.value)
        }
      },
      mounted() {
        this.$refs.inp.focus();
      },
    })
    // 课程列表组件
    Vue.component('course-list', {
      data() {
        return {
          selectedCourse: '',
        }
      },
      props: {
        courses: {
          type: Array,
          default: []
        }
      },
      template: `
        <div>
            <!-- 条件渲染 -->
            <p v-if="courses.length == 0">没有任何课程信息</p>
            
            <!-- 列表渲染 -->
            <!-- <div v-for="c in courses" :key="c" 
              :class="{active: selectedCourse === c}" @click="selectedCourse = c">
              {{ c }}
            </div> -->
            <!-- style -->
            <div class="course-list" v-else>
              <div v-for="c in courses" :key="c.name"
                :style="{backgroundColor: (selectedCourse === c ? '#ddd' : 'transparent')}"
                @click="selectedCourse = c">
                {{ c.name }} - ￥{{ c.price }}
              </div>
            </div>
        </div>
      `
    })

    // 模拟异步数据调用
    function getCourses() {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve([{ name: 'web全栈' }, { name: 'web高级' }])
        }, 2000);
      })
    }

    // 1.创建vue实例
    const app = new Vue({
      el: '#app',
      data() {
        return {
          title: '开课吧购物车',
          course: '',
          courses: [],
          totalCount: 0,
          // show: false,
          // showWarn: false,
          price: 0,
        }
      },
      async created() {
        // 组件实例已创建，由于未挂载，dom不存在
        const courses = await getCourses()
        this.courses = courses

        // 批量更新商品价格
        this.batchUpdate()
      },
      // mounted(){},
      methods: {
        addCourse() {
          if (this.course) {
            // 添加course到数组
            this.courses.push({ name: this.course })
            this.course = ''

            // 显示提示信息
            // this.show = true
            this.$refs.msgSuccess.toggle()
          } else {
            // 显示错误信息
            // this.showWarn = true
            this.$refs.msgWarning.toggle()
          }

        },
        batchUpdate() {
          this.courses.forEach(c => {
            // c.price = this.price
            this.$set(c, 'price', this.price)
            // Vue.set(c, 'price', this.price)
          })
        }
      },
      computed: {
        total() {
          // 计算属性有缓存性：如果值没有发生变化，则页面不回重新渲染
          return this.courses.length + '门'
        }
      },
      // 默认情况下watch初始化时不执行
      // watch: {
      //   courses(newValue, oldValue) {
      //     this.totalCount = newValue.length + '门'
      //   }
      // },
      watch: {
        courses: {
          immediate: true, // 立即执行一次
          // deep: true,
          handler(newValue, oldValue) {
            this.totalCount = newValue.length + '门'
          }
        }
      },
    })

  </script>
</body>

</html>